Original plot and data

For practice, you will try to recreate a plot published in the Economist issue of July 20th, 2016 showing the relationship between well-being and financial inclusion.

  • The original graph was taken from this article

  • You will generate this figure step by step through a series of included exercises using the tools we’ve just learned and will learn about.

The data for the exercises EconomistData.csv can be downloaded from the class github repository.

url <- paste0("https://raw.githubusercontent.com/cme195/cme195.github.io/",
              "master/assets/data/EconomistData.csv")
dat <- read.csv(url)
head(dat)

Exercise 1

  1. Create a scatter plot with percent of people over the age of 15 with a bank account on the x axis and the SEDA score on the y axis.
  2. Color the points in the previous plot blue.
  3. Color the points in the previous plot according to the Region.
  4. Create boxplots of SEDA scores by Region.
  5. Overlay points on top of the box plots
library(ggplot2)
#1. Create a scatter plot with percent of people over the age of 15 with a bank 
p <- ggplot(dat, aes(x = Percent.of.15plus.with.bank.account, y = SEDA.Current.level)) 
p + geom_point()

#2. Color the points in the previous plot blue.
p + geom_point(color = "blue")

#3. Color the points in the previous plot according to the `Region`.
p + geom_point(aes(color = Region))

#4. Create boxplots of SEDA scores by `Region`.
boxplot <- ggplot(dat, aes(x = Region, y = SEDA.Current.level)) + geom_boxplot() +
  theme(axis.text.x = element_text(angle = 15, hjust = 1))
boxplot

#5. Overlay points on top of the box plots
boxplot + geom_point()

#5. Overlay points on top of the box plots
boxplot + geom_jitter(width = 0.4)

Exercise 2

  1. Re-create a scatter plot with percent of people aged 15+ with a bank account on the x axis and SEDA current level score on the y axis (as you did in the previous exercise).
  2. Overlay a smoothing line on top of the scatter plot using the lm method. Hint: see ?geom_smooth.
  3. Overlay a smoothing line on top of the scatter plot using the default method.
  4. Overlay a smoothing line on top of the scatter plot using the default loess method, but make it less smooth. Hint: use a span argument, for details see ?loess.
#1. Re-create a scatter plot
p <- ggplot(dat, aes(x = Percent.of.15plus.with.bank.account, 
                     y = SEDA.Current.level))
(p <- p + geom_point())

#2. Overlay a smoothing line on top of the scatter plot using the lm method
p + geom_smooth(method = "lm")

# 3. Overlay a smoothing line on top of the scatter plot using the default method.
p + geom_smooth()

#4. Overlay a smoothing line on top of the scatter plot using the default loess 
# method, but make it less smooth
p + geom_smooth(span = 0.2)

Exercise 3

  1. Again generate a scatter plot of % of ppl aged 15+ with bank account vs SEDA score with points colored by region, like in Exercise 1.3. But this time choose the colors of the points yourself. Hint: see ?scale_color_manual.
p <- ggplot(dat, aes(Percent.of.15plus.with.bank.account, SEDA.Current.level)) 
(p <- p + geom_point(aes(color = Region)) + 
    scale_color_manual(values = c("#33BBFF", "darkgreen", "orange","#CA33FF", 
                                  "#B2FF33", "blue", "red")))

Exercise 4

  1. Facet by region (~ Region) the the Economist plot from Exercise 3.
p + facet_wrap(~ Region)

Exercise 5

Finish the Economist plot:

  1. Change ordering of the regions. Hint: convert “Region” column to a factor.
  2. Use the seetings for the markers to best match the points on the original Economist plot. Note that the points are bigger and have white borders, and specific fill colors. The following colors match the ones on the plot: colors <- c("#28AADC","#F2583F", "#76C0C1","#24576D", "#248E84","#DCC3AA", "#96503F")
  3. Add a linear trend.
  4. Change the axes ratio.
  5. Add a title and format the axes.
  6. Change the plot background and theme. Note that ggthemes package has a convenient functions for generating “Economist” style plots, e.g. theme_economist_white().
  7. Format the legend.
  8. Add “Country” labels yo the points.

Change order of the Regions

dat$Region <- as.character(dat$Region)
dat$Region <- factor(dat$Region, 
                     levels = c("Europe", "Asia", "Oceania", 
                                "North America", 
                                "Latin America & the Caribbean", 
                                "Middle East & North Africa",
                                "Sub-Saharan Africa"),
                     labels = c("Europe", "Asia", "Oceania", 
                                "North America", 
                                "Latin America & \n the Caribbean", 
                                "Middle East & \n North Africa",
                                "Sub-Saharan \n Africa"))
ggplot(dat, aes(Percent.of.15plus.with.bank.account, SEDA.Current.level)) + 
  geom_point(aes(color = Region))

Change the color scheme

colors <-  c("#28AADC","#F2583F", "#76C0C1","#24576D", "#248E84","#DCC3AA", "#96503F")
ggplot(dat, aes(Percent.of.15plus.with.bank.account, SEDA.Current.level)) + 
    geom_point(aes(fill = Region), color = "white", size = 4, pch = 21) +
    scale_fill_manual(name = "", values = colors)

Add the linear trend

p <- ggplot(dat, aes(Percent.of.15plus.with.bank.account, SEDA.Current.level)) + 
  geom_smooth(method = "lm", se = FALSE, col = "black", size = 0.5) +
  geom_point(aes(fill = Region), color = "white", size = 4, pch = 21) +
  scale_fill_manual(name = "", values = colors)
p

Change the axes ratio.

(p <- p + coord_fixed(ratio = 0.4))

Add a title and format the axes

(p <- p +
  scale_x_continuous(name = "% of people aged 15+ with bank account, 2014",
                     limits = c(0, 100),
                     breaks = seq(0, 100, by = 20)) +
  scale_y_continuous(name = "SEDA Score, 100=maximum",
                     limits = c(0, 100),
                     breaks = seq(0, 100, by = 20)) +
   labs(title="Laughing all the way to the bank",
        subtitle="Well-being and financial inclusion* \n 2014-15"))

Change the background and theme

You can check out the ggthemes package which implement the themes that make your plots look like they came from:

  • Base graphics
  • Tableau
  • Excel
  • Stata
  • Economist
  • Wall Street Journal
  • Edward Tufte
  • Nate Silver’s Fivethirtyeight
  • etc.
#install.packages("ggthemes")
library(ggthemes)
(p <- p + theme_economist_white(gray_bg = FALSE))

Format the legend

(p <- p +
   theme(text = element_text(color = "grey35", size = 11),
         legend.text = element_text(size = 10),
         legend.position = c(0.72, 1.12),   
         legend.direction = "horizontal",
         plot.title = element_text(size = rel(1.2), color = "black"),
         plot.margin = unit(c(1, 1.5, 1.5, 0.5), "cm")) +
  guides(fill = guide_legend(ncol = 4, byrow = FALSE)))

Add point labels

pointsToLabel <- c("Yemen", "Iraq", "Egypt", "Jordan", "Chad", "Congo", 
                   "Angola", "Albania", "Zimbabwe", "Uganda", "Nigeria",
                   "Uruguay", "Kazakhstan", "India", "Turkey", "South Africa",
                   "Kenya", "Russia", "Brazil", "Chile", "Saudi Arabia", 
                   "Poland", "China", "Serbia", "United States", "United Kingdom")
# install.packages("ggrepel")
library(dplyr); library(ggrepel)
(p <-  p + 
    geom_text_repel(aes(label = Country), color = "grey20",
                        data = dat %>% filter(Country %in% pointsToLabel),
                        force = 15))

Add notes to the bottom and save the plot

Use “grid.text()” to add notes

library(grid)
png(file = "./econScatter.png", width = 750, height = 400)
p
grid.text("Source: Boston Consulting Group",
          x = 0.02, y = 0.02, just = "left",
          gp = gpar(fontsize = 10, col="grey37"))
grid.text("*Data available for 123 countries \n Sustainable economic development assesment",
          x = 0.92, y = .05, just = "right",
          gp = gpar(fontsize = 10, col = "grey37"))
dev.off()
null device 
          1 

Similar to the original:

LS0tCnRpdGxlOiAiTGVjdHVyZSA0OiBFeGVyY2lzZXMgd2l0aCBhbnN3ZXJzIgpkYXRlOiBPY3RvYmVyIDEydGgsIDIwMTcKb3V0cHV0OiAKICBodG1sX25vdGVib29rOgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKLS0tCgojIE9yaWdpbmFsIHBsb3QgYW5kIGRhdGEKCkZvciBwcmFjdGljZSwgeW91IHdpbGwgdHJ5IHRvIHJlY3JlYXRlCmEgcGxvdCBwdWJsaXNoZWQgaW4gdGhlIEVjb25vbWlzdCBpc3N1ZSBvZiBKdWx5IDIwdGgsIDIwMTYgc2hvd2luZwp0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gd2VsbC1iZWluZyBhbmQgZmluYW5jaWFsIGluY2x1c2lvbi4KCiFbXSguLi9kYXRhL2Vjb25vbWlzdC5wbmcpCgoqIFRoZSBvcmlnaW5hbCBncmFwaCB3YXMgdGFrZW4gZnJvbSB0aGlzIApbYXJ0aWNsZV0oaHR0cDovL3d3dy5lY29ub21pc3QuY29tL2Jsb2dzL2dyYXBoaWNkZXRhaWwvMjAxNi8wNy9kYWlseS1jaGFydC0xMykKCiogWW91IHdpbGwgZ2VuZXJhdGUgdGhpcyBmaWd1cmUgc3RlcCBieSBzdGVwIHRocm91Z2ggYSBzZXJpZXMgb2YgaW5jbHVkZWQgCmV4ZXJjaXNlcyB1c2luZyB0aGUgdG9vbHMgd2UndmUganVzdCBsZWFybmVkIGFuZCB3aWxsIGxlYXJuIGFib3V0LiAKCgpUaGUgZGF0YSBmb3IgdGhlIGV4ZXJjaXNlcyBgRWNvbm9taXN0RGF0YS5jc3ZgIGNhbiBiZSBkb3dubG9hZGVkIGZyb20gCnRoZSBjbGFzcyBnaXRodWIgcmVwb3NpdG9yeS4KCmBgYHtyfQp1cmwgPC0gcGFzdGUwKCJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vY21lMTk1L2NtZTE5NS5naXRodWIuaW8vIiwKICAgICAgICAgICAgICAibWFzdGVyL2Fzc2V0cy9kYXRhL0Vjb25vbWlzdERhdGEuY3N2IikKZGF0IDwtIHJlYWQuY3N2KHVybCkKaGVhZChkYXQpCmBgYAoKCiMgRXhlcmNpc2UgMQoKMS4gQ3JlYXRlIGEgc2NhdHRlciBwbG90IHdpdGggcGVyY2VudCBvZiBwZW9wbGUgb3ZlciB0aGUgYWdlCm9mIDE1IHdpdGggYSBiYW5rIGFjY291bnQgb24gdGhlIHggYXhpcyBhbmQgdGhlIFNFREEgc2NvcmUgb24gdGhlIHkgYXhpcy4KMi4gQ29sb3IgdGhlIHBvaW50cyBpbiB0aGUgcHJldmlvdXMgcGxvdCBibHVlLgozLiBDb2xvciB0aGUgcG9pbnRzIGluIHRoZSBwcmV2aW91cyBwbG90IGFjY29yZGluZyB0byB0aGUgYFJlZ2lvbmAuCjQuIENyZWF0ZSBib3hwbG90cyBvZiBTRURBIHNjb3JlcyBieSBgUmVnaW9uYC4KNS4gT3ZlcmxheSBwb2ludHMgb24gdG9wIG9mIHRoZSBib3ggcGxvdHMKCgpgYGB7cn0KbGlicmFyeShnZ3Bsb3QyKQojMS4gQ3JlYXRlIGEgc2NhdHRlciBwbG90IHdpdGggcGVyY2VudCBvZiBwZW9wbGUgb3ZlciB0aGUgYWdlIG9mIDE1IHdpdGggYSBiYW5rIApwIDwtIGdncGxvdChkYXQsIGFlcyh4ID0gUGVyY2VudC5vZi4xNXBsdXMud2l0aC5iYW5rLmFjY291bnQsIHkgPSBTRURBLkN1cnJlbnQubGV2ZWwpKSAKcCArIGdlb21fcG9pbnQoKQpgYGAKCmBgYHtyfQojMi4gQ29sb3IgdGhlIHBvaW50cyBpbiB0aGUgcHJldmlvdXMgcGxvdCBibHVlLgpwICsgZ2VvbV9wb2ludChjb2xvciA9ICJibHVlIikKYGBgCgpgYGB7cn0KIzMuIENvbG9yIHRoZSBwb2ludHMgaW4gdGhlIHByZXZpb3VzIHBsb3QgYWNjb3JkaW5nIHRvIHRoZSBgUmVnaW9uYC4KcCArIGdlb21fcG9pbnQoYWVzKGNvbG9yID0gUmVnaW9uKSkKYGBgCgpgYGB7cn0KIzQuIENyZWF0ZSBib3hwbG90cyBvZiBTRURBIHNjb3JlcyBieSBgUmVnaW9uYC4KYm94cGxvdCA8LSBnZ3Bsb3QoZGF0LCBhZXMoeCA9IFJlZ2lvbiwgeSA9IFNFREEuQ3VycmVudC5sZXZlbCkpICsgZ2VvbV9ib3hwbG90KCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMTUsIGhqdXN0ID0gMSkpCmJveHBsb3QKYGBgCgpgYGB7cn0KIzUuIE92ZXJsYXkgcG9pbnRzIG9uIHRvcCBvZiB0aGUgYm94IHBsb3RzCmJveHBsb3QgKyBnZW9tX3BvaW50KCkKYGBgCgpgYGB7cn0KIzUuIE92ZXJsYXkgcG9pbnRzIG9uIHRvcCBvZiB0aGUgYm94IHBsb3RzCmJveHBsb3QgKyBnZW9tX2ppdHRlcih3aWR0aCA9IDAuNCkKYGBgCgoKIyBFeGVyY2lzZSAyCgoxLiBSZS1jcmVhdGUgYSBzY2F0dGVyIHBsb3Qgd2l0aCBwZXJjZW50IG9mIHBlb3BsZSBhZ2VkIDE1KyB3aXRoIGEgYmFuayBhY2NvdW50Cm9uIHRoZSB4IGF4aXMgYW5kIFNFREEgY3VycmVudCBsZXZlbCBzY29yZSBvbiB0aGUgeSBheGlzIAooYXMgeW91IGRpZCBpbiB0aGUgcHJldmlvdXMgZXhlcmNpc2UpLgoyLiBPdmVybGF5IGEgc21vb3RoaW5nIGxpbmUgb24gdG9wIG9mIHRoZSBzY2F0dGVyIHBsb3QgdXNpbmcgdGhlIGxtIG1ldGhvZC4gCkhpbnQ6IHNlZSBgP2dlb21fc21vb3RoYC4KMy4gT3ZlcmxheSBhIHNtb290aGluZyBsaW5lIG9uIHRvcCBvZiB0aGUgc2NhdHRlciBwbG90IHVzaW5nIHRoZSBkZWZhdWx0IG1ldGhvZC4KNC4gT3ZlcmxheSBhIHNtb290aGluZyBsaW5lIG9uIHRvcCBvZiB0aGUgc2NhdHRlciBwbG90IHVzaW5nIHRoZSBkZWZhdWx0IGxvZXNzIAptZXRob2QsIGJ1dCBtYWtlIGl0IGxlc3Mgc21vb3RoLiBIaW50OiB1c2UgYSBgc3BhbmAgYXJndW1lbnQsIGZvciBkZXRhaWxzIHNlZSBgP2xvZXNzYC4KCmBgYHtyfQojMS4gUmUtY3JlYXRlIGEgc2NhdHRlciBwbG90CnAgPC0gZ2dwbG90KGRhdCwgYWVzKHggPSBQZXJjZW50Lm9mLjE1cGx1cy53aXRoLmJhbmsuYWNjb3VudCwgCiAgICAgICAgICAgICAgICAgICAgIHkgPSBTRURBLkN1cnJlbnQubGV2ZWwpKQoocCA8LSBwICsgZ2VvbV9wb2ludCgpKQpgYGAKCmBgYHtyfQojMi4gT3ZlcmxheSBhIHNtb290aGluZyBsaW5lIG9uIHRvcCBvZiB0aGUgc2NhdHRlciBwbG90IHVzaW5nIHRoZSBsbSBtZXRob2QKcCArIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIpCmBgYAoKYGBge3J9CiMgMy4gT3ZlcmxheSBhIHNtb290aGluZyBsaW5lIG9uIHRvcCBvZiB0aGUgc2NhdHRlciBwbG90IHVzaW5nIHRoZSBkZWZhdWx0IG1ldGhvZC4KcCArIGdlb21fc21vb3RoKCkKYGBgCgpgYGB7cn0KIzQuIE92ZXJsYXkgYSBzbW9vdGhpbmcgbGluZSBvbiB0b3Agb2YgdGhlIHNjYXR0ZXIgcGxvdCB1c2luZyB0aGUgZGVmYXVsdCBsb2VzcyAKIyBtZXRob2QsIGJ1dCBtYWtlIGl0IGxlc3Mgc21vb3RoCnAgKyBnZW9tX3Ntb290aChzcGFuID0gMC4yKQpgYGAKCgojIEV4ZXJjaXNlIDMKCjEuIEFnYWluIGdlbmVyYXRlIGEgc2NhdHRlciBwbG90IG9mICUgb2YgcHBsIGFnZWQgMTUrIHdpdGggYmFuayBhY2NvdW50IAp2cyBTRURBIHNjb3JlIHdpdGggcG9pbnRzIGNvbG9yZWQgYnkgcmVnaW9uLCBsaWtlIGluIEV4ZXJjaXNlIDEuMy4KQnV0IHRoaXMgdGltZSBjaG9vc2UgdGhlIGNvbG9ycyBvZiB0aGUgcG9pbnRzIHlvdXJzZWxmLgpIaW50OiBzZWUgYD9zY2FsZV9jb2xvcl9tYW51YWxgLgoKYGBge3J9CnAgPC0gZ2dwbG90KGRhdCwgYWVzKFBlcmNlbnQub2YuMTVwbHVzLndpdGguYmFuay5hY2NvdW50LCBTRURBLkN1cnJlbnQubGV2ZWwpKSAKKHAgPC0gcCArIGdlb21fcG9pbnQoYWVzKGNvbG9yID0gUmVnaW9uKSkgKyAKICAgIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCIjMzNCQkZGIiwgImRhcmtncmVlbiIsICJvcmFuZ2UiLCIjQ0EzM0ZGIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiI0IyRkYzMyIsICJibHVlIiwgInJlZCIpKSkKYGBgCgojIEV4ZXJjaXNlIDQKCjEuIEZhY2V0ICBieSByZWdpb24gKGB+IFJlZ2lvbmApIHRoZSB0aGUgRWNvbm9taXN0IHBsb3QgZnJvbSBFeGVyY2lzZSAzLgoKYGBge3J9CnAgKyBmYWNldF93cmFwKH4gUmVnaW9uKQpgYGAKCgoKIyBFeGVyY2lzZSA1CgpGaW5pc2ggdGhlIEVjb25vbWlzdCBwbG90OgoKMS4gQ2hhbmdlIG9yZGVyaW5nIG9mIHRoZSByZWdpb25zLiBIaW50OiBjb252ZXJ0ICJSZWdpb24iIGNvbHVtbiB0byBhIGZhY3Rvci4KMi4gVXNlIHRoZSBzZWV0aW5ncyBmb3IgdGhlIG1hcmtlcnMgdG8gYmVzdCBtYXRjaCB0aGUgcG9pbnRzIG9uIHRoZSBvcmlnaW5hbCAKRWNvbm9taXN0IHBsb3QuIE5vdGUgdGhhdCB0aGUgcG9pbnRzIGFyZSBiaWdnZXIgYW5kIGhhdmUgd2hpdGUgYm9yZGVycywKYW5kIHNwZWNpZmljIGZpbGwgY29sb3JzLiBUaGUgZm9sbG93aW5nIGNvbG9ycyBtYXRjaCB0aGUgb25lcyBvbiB0aGUgcGxvdDoKYGNvbG9ycyA8LSAgYygiIzI4QUFEQyIsIiNGMjU4M0YiLCAiIzc2QzBDMSIsIiMyNDU3NkQiLCAiIzI0OEU4NCIsIiNEQ0MzQUEiLCAiIzk2NTAzRiIpYAozLiBBZGQgYSBsaW5lYXIgdHJlbmQuCjQuIENoYW5nZSB0aGUgYXhlcyByYXRpby4KNS4gQWRkIGEgdGl0bGUgYW5kIGZvcm1hdCB0aGUgYXhlcy4KNi4gQ2hhbmdlIHRoZSBwbG90IGJhY2tncm91bmQgYW5kIHRoZW1lLiBOb3RlIHRoYXQgYGdndGhlbWVzYCBwYWNrYWdlCmhhcyBhIGNvbnZlbmllbnQgZnVuY3Rpb25zIGZvciBnZW5lcmF0aW5nICJFY29ub21pc3QiIHN0eWxlIHBsb3RzLCAKZS5nLiBgdGhlbWVfZWNvbm9taXN0X3doaXRlKClgLgo3LiBGb3JtYXQgdGhlIGxlZ2VuZC4KOC4gQWRkICJDb3VudHJ5IiBsYWJlbHMgeW8gdGhlIHBvaW50cy4KCgojIyMgQ2hhbmdlIG9yZGVyIG9mIHRoZSBSZWdpb25zCgpgYGB7cn0KZGF0JFJlZ2lvbiA8LSBhcy5jaGFyYWN0ZXIoZGF0JFJlZ2lvbikKZGF0JFJlZ2lvbiA8LSBmYWN0b3IoZGF0JFJlZ2lvbiwgCiAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIkV1cm9wZSIsICJBc2lhIiwgIk9jZWFuaWEiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTm9ydGggQW1lcmljYSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJMYXRpbiBBbWVyaWNhICYgdGhlIENhcmliYmVhbiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNaWRkbGUgRWFzdCAmIE5vcnRoIEFmcmljYSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlN1Yi1TYWhhcmFuIEFmcmljYSIpLAogICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJFdXJvcGUiLCAiQXNpYSIsICJPY2VhbmlhIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5vcnRoIEFtZXJpY2EiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTGF0aW4gQW1lcmljYSAmIFxuIHRoZSBDYXJpYmJlYW4iLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTWlkZGxlIEVhc3QgJiBcbiBOb3J0aCBBZnJpY2EiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTdWItU2FoYXJhbiBcbiBBZnJpY2EiKSkKYGBgCgoKYGBge3J9CmdncGxvdChkYXQsIGFlcyhQZXJjZW50Lm9mLjE1cGx1cy53aXRoLmJhbmsuYWNjb3VudCwgU0VEQS5DdXJyZW50LmxldmVsKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvciA9IFJlZ2lvbikpCmBgYAoKIyMjIENoYW5nZSB0aGUgY29sb3Igc2NoZW1lCgpgYGB7cn0KY29sb3JzIDwtICBjKCIjMjhBQURDIiwiI0YyNTgzRiIsICIjNzZDMEMxIiwiIzI0NTc2RCIsICIjMjQ4RTg0IiwiI0RDQzNBQSIsICIjOTY1MDNGIikKZ2dwbG90KGRhdCwgYWVzKFBlcmNlbnQub2YuMTVwbHVzLndpdGguYmFuay5hY2NvdW50LCBTRURBLkN1cnJlbnQubGV2ZWwpKSArIAogICAgZ2VvbV9wb2ludChhZXMoZmlsbCA9IFJlZ2lvbiksIGNvbG9yID0gIndoaXRlIiwgc2l6ZSA9IDQsIHBjaCA9IDIxKSArCiAgICBzY2FsZV9maWxsX21hbnVhbChuYW1lID0gIiIsIHZhbHVlcyA9IGNvbG9ycykKYGBgCgoKIyMjIEFkZCB0aGUgbGluZWFyIHRyZW5kCgpgYGB7cn0KcCA8LSBnZ3Bsb3QoZGF0LCBhZXMoUGVyY2VudC5vZi4xNXBsdXMud2l0aC5iYW5rLmFjY291bnQsIFNFREEuQ3VycmVudC5sZXZlbCkpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBGQUxTRSwgY29sID0gImJsYWNrIiwgc2l6ZSA9IDAuNSkgKwogIGdlb21fcG9pbnQoYWVzKGZpbGwgPSBSZWdpb24pLCBjb2xvciA9ICJ3aGl0ZSIsIHNpemUgPSA0LCBwY2ggPSAyMSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKG5hbWUgPSAiIiwgdmFsdWVzID0gY29sb3JzKQpwCmBgYAoKIyMjIENoYW5nZSB0aGUgYXhlcyByYXRpby4KCmBgYHtyfQoocCA8LSBwICsgY29vcmRfZml4ZWQocmF0aW8gPSAwLjQpKQpgYGAKCgojIyMgQWRkIGEgdGl0bGUgYW5kIGZvcm1hdCB0aGUgYXhlcwoKYGBge3J9CihwIDwtIHAgKwogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIiUgb2YgcGVvcGxlIGFnZWQgMTUrIHdpdGggYmFuayBhY2NvdW50LCAyMDE0IiwKICAgICAgICAgICAgICAgICAgICAgbGltaXRzID0gYygwLCAxMDApLAogICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBzZXEoMCwgMTAwLCBieSA9IDIwKSkgKwogIHNjYWxlX3lfY29udGludW91cyhuYW1lID0gIlNFREEgU2NvcmUsIDEwMD1tYXhpbXVtIiwKICAgICAgICAgICAgICAgICAgICAgbGltaXRzID0gYygwLCAxMDApLAogICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBzZXEoMCwgMTAwLCBieSA9IDIwKSkgKwogICBsYWJzKHRpdGxlPSJMYXVnaGluZyBhbGwgdGhlIHdheSB0byB0aGUgYmFuayIsCiAgICAgICAgc3VidGl0bGU9IldlbGwtYmVpbmcgYW5kIGZpbmFuY2lhbCBpbmNsdXNpb24qIFxuIDIwMTQtMTUiKSkKYGBgCgojIyMgQ2hhbmdlIHRoZSBiYWNrZ3JvdW5kIGFuZCB0aGVtZQoKWW91IGNhbiBjaGVjayBvdXQgdGhlIFtgZ2d0aGVtZXNgXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvZ2d0aGVtZXMvdmlnbmV0dGVzL2dndGhlbWVzLmh0bWwpIApwYWNrYWdlIHdoaWNoIGltcGxlbWVudCB0aGUgdGhlbWVzIHRoYXQgbWFrZSB5b3VyIHBsb3RzIGxvb2sgbGlrZSB0aGV5IGNhbWUgZnJvbToKCiogQmFzZSBncmFwaGljcwoqIFRhYmxlYXUKKiBFeGNlbAoqIFN0YXRhCiogRWNvbm9taXN0CiogV2FsbCBTdHJlZXQgSm91cm5hbAoqIEVkd2FyZCBUdWZ0ZQoqIE5hdGUgU2lsdmVyJ3MgRml2ZXRoaXJ0eWVpZ2h0CiogZXRjLgoKYGBge3J9CiNpbnN0YWxsLnBhY2thZ2VzKCJnZ3RoZW1lcyIpCmxpYnJhcnkoZ2d0aGVtZXMpCihwIDwtIHAgKyB0aGVtZV9lY29ub21pc3Rfd2hpdGUoZ3JheV9iZyA9IEZBTFNFKSkKYGBgCgojIyMgRm9ybWF0IHRoZSBsZWdlbmQKCmBgYHtyLCBmaWcud2lkdGg9OSwgZmlnLmhlaWdodD01fQoocCA8LSBwICsKICAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJncmV5MzUiLCBzaXplID0gMTEpLAogICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgICAgICBsZWdlbmQucG9zaXRpb24gPSBjKDAuNzIsIDEuMTIpLCAgIAogICAgICAgICBsZWdlbmQuZGlyZWN0aW9uID0gImhvcml6b250YWwiLAogICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSByZWwoMS4yKSwgY29sb3IgPSAiYmxhY2siKSwKICAgICAgICAgcGxvdC5tYXJnaW4gPSB1bml0KGMoMSwgMS41LCAxLjUsIDAuNSksICJjbSIpKSArCiAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQobmNvbCA9IDQsIGJ5cm93ID0gRkFMU0UpKSkKYGBgCgojIyMgQWRkIHBvaW50IGxhYmVscwoKYGBge3J9CnBvaW50c1RvTGFiZWwgPC0gYygiWWVtZW4iLCAiSXJhcSIsICJFZ3lwdCIsICJKb3JkYW4iLCAiQ2hhZCIsICJDb25nbyIsIAogICAgICAgICAgICAgICAgICAgIkFuZ29sYSIsICJBbGJhbmlhIiwgIlppbWJhYndlIiwgIlVnYW5kYSIsICJOaWdlcmlhIiwKICAgICAgICAgICAgICAgICAgICJVcnVndWF5IiwgIkthemFraHN0YW4iLCAiSW5kaWEiLCAiVHVya2V5IiwgIlNvdXRoIEFmcmljYSIsCiAgICAgICAgICAgICAgICAgICAiS2VueWEiLCAiUnVzc2lhIiwgIkJyYXppbCIsICJDaGlsZSIsICJTYXVkaSBBcmFiaWEiLCAKICAgICAgICAgICAgICAgICAgICJQb2xhbmQiLCAiQ2hpbmEiLCAiU2VyYmlhIiwgIlVuaXRlZCBTdGF0ZXMiLCAiVW5pdGVkIEtpbmdkb20iKQpgYGAKCmBgYHtyLCBmaWcud2lkdGg9OSwgZmlnLmhlaWdodD01fQojIGluc3RhbGwucGFja2FnZXMoImdncmVwZWwiKQpsaWJyYXJ5KGRwbHlyKTsgbGlicmFyeShnZ3JlcGVsKQoocCA8LSAgcCArIAogICAgZ2VvbV90ZXh0X3JlcGVsKGFlcyhsYWJlbCA9IENvdW50cnkpLCBjb2xvciA9ICJncmV5MjAiLAogICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGF0ICU+JSBmaWx0ZXIoQ291bnRyeSAlaW4lIHBvaW50c1RvTGFiZWwpLAogICAgICAgICAgICAgICAgICAgICAgICBmb3JjZSA9IDE1KSkKYGBgCgojIyMgQWRkIG5vdGVzIHRvIHRoZSBib3R0b20gYW5kIHNhdmUgdGhlIHBsb3QKClVzZSAiZ3JpZC50ZXh0KCkiIHRvIGFkZCBub3RlcwoKYGBge3J9CmxpYnJhcnkoZ3JpZCkKcG5nKGZpbGUgPSAiLi4vZGF0YS9lY29uU2NhdHRlci5wbmciLCB3aWR0aCA9IDc1MCwgaGVpZ2h0ID0gNDAwKQpwCmdyaWQudGV4dCgiU291cmNlOiBCb3N0b24gQ29uc3VsdGluZyBHcm91cCIsCiAgICAgICAgICB4ID0gMC4wMiwgeSA9IDAuMDIsIGp1c3QgPSAibGVmdCIsCiAgICAgICAgICBncCA9IGdwYXIoZm9udHNpemUgPSAxMCwgY29sPSJncmV5MzciKSkKZ3JpZC50ZXh0KCIqRGF0YSBhdmFpbGFibGUgZm9yIDEyMyBjb3VudHJpZXMgXG4gU3VzdGFpbmFibGUgZWNvbm9taWMgZGV2ZWxvcG1lbnQgYXNzZXNtZW50IiwKICAgICAgICAgIHggPSAwLjkyLCB5ID0gLjA1LCBqdXN0ID0gInJpZ2h0IiwKICAgICAgICAgIGdwID0gZ3Bhcihmb250c2l6ZSA9IDEwLCBjb2wgPSAiZ3JleTM3IikpCmRldi5vZmYoKQpgYGAKCgohW10oLi4vZGF0YS9lY29uU2NhdHRlci5wbmcpCgoKU2ltaWxhciB0byB0aGUgb3JpZ2luYWw6CgohW10oLi4vZGF0YS9lY29ub21pc3QucG5nKQo=